﻿using System;
using System.Drawing;
using System.Windows.Forms;
using AiFrame.InterfaceLib.Data.Patterns;
using AiFrame.InterfaceLib.MVP;
using AiFrame.InterfaceLib.Windows.Controls;

//using NavigationBar.Properties;

namespace AiFrame.Windows.Controls.NavigationBar
{
    public partial class NavigationBarView : UserControl, INavigationBar, IObserver
    {
        private readonly INavigationBarTheme _navigationBarTheme;
        private readonly IDataNavigationBarTheme _dataNavigationBarTheme;
        private ObservableCollection<NavigationBarButton> buttonCollection;

        public NavigationBarView(INavigationBarTheme navigationBarTheme, IDataNavigationBarTheme dataNavigationBarTheme)
        {
            this._navigationBarTheme = navigationBarTheme;
            _dataNavigationBarTheme = dataNavigationBarTheme;
            InitializeComponent();
            Init();

        }

        private void Init()
        {
            topPictureBox.Image = _navigationBarTheme.GetNavBarHeaderImage();
            bottomPictureBox.Image = _navigationBarTheme.GetNavBarFooterImage();

            // TODO: Die Hintergrundfarbe muss beim aktuellen Control eingesetzt werden
            //this.BackColor = _navigationBarTheme.GetNavBarContentArea();

            /* Variablen initialisieren */
            buttonCollection = new ObservableCollection<NavigationBarButton>();
            buttonCollection.RegisterObserver(this);
            
        }

        #region Implementation of INavigationBar

        public IDataNavigationBar AddButton(string name, string caption, string hoverText,
                              Image image)
        {
            /* Alle Buttons durchgehen und prüfen, ob bereits einer
             * mit demselben Namen vorhanen ist */
            IDataNavigationBar navigationBar = null;
            foreach (NavigationBarButton button in buttonCollection)
            {
                if (button.Caption == caption)
                    navigationBar = button.DataNavigationbar;
            }

            /* Falls kein Button mit gleichem Namen gefunden wurde, dann
             * neue DataNavigationBar erzeugen */
            if (navigationBar == null)
            {
                navigationBar = new DataNavigationBar.DataNavigationBar(_dataNavigationBarTheme);
                navigationBar.SetParent(contentPanel);
                ((DataNavigationBar.DataNavigationBar) navigationBar).ShowHeader = false;
                navigationBar.SetDockingStyle(DockStyle.Fill);

                NavigationBarButton nb = new NavigationBarButton(_navigationBarTheme,
                name, caption, hoverText, image, navigationBar);
                nb.RegisterObserver(this);
                buttonCollection.Add(nb);
            }

            /* Der erste Button soll immer aktiviert sein */
            buttonCollection[0].State = NavBarButtonState.Pressed;

            return navigationBar;
        }

        public void AddButton(string name, string caption, string hoverText, Image image, IDataNavigationBar dataNavigationBar, OnClickProcedure clickProcedure)
        {
            NavigationBarButton nb = new NavigationBarButton(_navigationBarTheme, name, caption, hoverText, image, dataNavigationBar);
            nb.OnClickProcedure = clickProcedure;
            dataNavigationBar.SetParent(contentPanel);
            
            nb.RegisterObserver(this);
            buttonCollection.Add(nb);

            buttonCollection[0].State = NavBarButtonState.Pressed;
        }

        public IDataNavigationBar CreateDataNavigationBar()
        {
            DataNavigationBar.DataNavigationBar dataNavigationBar = new DataNavigationBar.DataNavigationBar(_dataNavigationBarTheme);
            dataNavigationBar.ShowHeader = false;
            dataNavigationBar.SetDockingStyle(DockStyle.Fill);

            return dataNavigationBar;
        }

        public void SetParent(object parent)
        {
            Control control = (Control) parent;
            Parent = control;
        }

        public void SetDockingStyle(object dockingStyle)
        {
            DockStyle ds = (DockStyle) dockingStyle;

            Dock = ds;
        }

        #endregion

        public void NotifyChanges(object sender, object obj)
        {
            if (sender is ObservableCollection<NavigationBarButton>)
            {
                /* Alle Docking-Styles zurücksetzen, und anschließend
                 * nacheinander wieder aktivieren, weil die NavbarButtons
                 * in der Reihenfolge wie in der Liste erscheinen sollen.
                 */
                foreach (NavigationBarButton btn in buttonCollection)
                {
                    btn.Dock = DockStyle.None;
                }
                
                foreach (NavigationBarButton btn in buttonCollection)
                {
                    btn.Dock = DockStyle.Bottom;
                    btn.Parent = this;
                    btn.Top = 0;
                }

                /* Die PictureBox soll am unteren Rand bleiben,
                 * deshalb müssen die Eigenschaften am Ende neu
                 * gesetzt werden. */
                BottomPanel.Parent = null;
                BottomPanel.Dock = DockStyle.None;
                BottomPanel.Parent = this;
                BottomPanel.Dock = DockStyle.Bottom;

            } else if (sender is NavigationBarButton)
            {
                NavigationBarButton nb = (NavigationBarButton)sender;
                /* Wenn die sich geänderte Schaltfläche den Status "Pressed"
                 * hat, dann sollen alle anderen wieder den Status "Normal"
                 * bekommen. */
                if (nb.State == NavBarButtonState.Pressed)
                {
                    foreach(NavigationBarButton curBtn in buttonCollection)
                    {
                        /* Status auf Normal setzen, falls es nicht
                         * der Button ist, der sich grad geändert hat */
                        if (curBtn != nb)
                            curBtn.State = NavBarButtonState.Normal;
                    }
                    Caption = nb.Caption;
                }
            }
            
        }

        private void topPictureBox_Paint(object sender, PaintEventArgs e)
        {
            /* Anstatt dem groupLabel muss ein transparenter Text gezeichnet
             * werden, da das Label nicht auf transparent gesetzt werden kann. */
            groupLabel.Visible = false;
            e.Graphics.DrawString(groupLabel.Text, groupLabel.Font,
                                  new SolidBrush(groupLabel.ForeColor), groupLabel.Left - topPictureBox.Left,
                                  groupLabel.Top - topPictureBox.Top);
        }

        /// <summary>
        /// Mithilfe dieser Eigenschaft wird die Titelzeile der Navbar
        /// geändert.
        /// </summary>
        public String Caption
        {
            set
            {
                groupLabel.Text = value;

                /* PictureBox aktualisieren, damit das Label neu
                 * gezeichnet wird. */
                topPictureBox.Refresh();
            }
        }
    }
}